/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 *//*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package company.abstractClasses;

import comparators.abstraction.CandidateCapableComparator;
import entities.Country;
import entities.Province;
import entities.Search;
import entities.SearchEducationalInfoRequerimentAndOperator;
import entities.SearchEducationalInfoRequerimentOrOperator;
import entities.SearchInterestAreaRequerimentAndOperator;
import entities.SearchInterestAreaRequerimentOrOperator;
import entities.SearchLanguageInfoRequerimentAndOperator;
import entities.SearchLanguageInfoRequerimentOrOperator;
import entities.SearchProfessionalInfoRequerimentAndOperator;
import entities.SearchProfessionalInfoRequerimentOrOperator;
import entities.SearchRelocatingInfoRequerimentAndOperator;
import entities.SearchRelocatingInfoRequerimentOrOperator;
import entities.Sex;
import entities.TimeAvailability;
import entities.Town;
import facades.AbstractFacade;
import interfaces.CandidateCapable;
import interfaces.SearchCapable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletRequest;
import util.filter.CollectionsFilter;
import util.filter.Predicate;

/**
 *
 * @author damfercer
 * @param <T>
 * @param <F>
 * @param <C>
 * @param <P>
 */
public abstract class AbstractCandidateCapableFilterList<T extends CandidateCapable,F extends AbstractFacade<T>, C extends CandidateCapableComparator<T,P>, P extends Predicate<T> & SearchCapable> extends CompanyAbstractEntityList<T, F> {
    private P predicate;
    private SearchEducationalInfoRequerimentAndOperator educationalAndCollector;
    private SearchEducationalInfoRequerimentOrOperator educationalOrCollector;
    private SearchInterestAreaRequerimentAndOperator interestAreaAndCollector;
    private SearchInterestAreaRequerimentOrOperator interestAreaOrCollector;
    private SearchLanguageInfoRequerimentAndOperator languageAndCollector;
    private SearchLanguageInfoRequerimentOrOperator languageOrCollector;
    private SearchProfessionalInfoRequerimentAndOperator professionalAndCollector;
    private SearchProfessionalInfoRequerimentOrOperator professionalOrCollector;
    private SearchRelocatingInfoRequerimentAndOperator relocatingAndCollector;
    private SearchRelocatingInfoRequerimentOrOperator relocatingOrCollector;
    private Integer importance;
    private List<T> baseEntityList;
    private final Integer important=3;
    private final Integer normal=1;
    private final Integer obligatory=0;
    private final Integer numberOfFaces =20;
    private Sex sex;
    private Integer minAge;
    private Integer maxAge;
    private Country residenceCountry;
    private Province residenceProvince;
    private Town residenceTown;
    private TimeAvailability timeAvailability;
    private Boolean requiredVehicle;    
    private String keywords;
    
    @PostConstruct
    @Override
    public void init(){
        setPredicate(getNewPredicateInstance());
        setEntityFacade(getEntityFacadeInstance().get());
        setEntityList(new ArrayList<T>());
        setBaseEntityList(new ArrayList<T>());
        initSearch();
    }   
    
    public void initSearch(){
        if(getPredicate().getSearch().getSearchEducationalInfoRequerimentAndOperatorList()==null){
            getPredicate().getSearch().setSearchEducationalInfoRequerimentAndOperatorList(new ArrayList<SearchEducationalInfoRequerimentAndOperator>());
        }
        if(getPredicate().getSearch().getSearchEducationalInfoRequerimentOrOperatorList()==null){
            getPredicate().getSearch().setSearchEducationalInfoRequerimentOrOperatorList(new ArrayList<SearchEducationalInfoRequerimentOrOperator>());
        }
        if(getPredicate().getSearch().getSearchInterestAreaRequerimentAndOperatorList()==null){
            getPredicate().getSearch().setSearchInterestAreaRequerimentAndOperatorList(new ArrayList<SearchInterestAreaRequerimentAndOperator>());
        }
        if(getPredicate().getSearch().getSearchInterestAreaRequerimentOrOperatorList()==null){
            getPredicate().getSearch().setSearchInterestAreaRequerimentOrOperatorList(new ArrayList<SearchInterestAreaRequerimentOrOperator>());
        }
        if(getPredicate().getSearch().getSearchInterestAreaRequerimentOrOperatorList()==null){
            getPredicate().getSearch().setSearchLanguageInfoRequerimentAndOperatorList(new ArrayList<SearchLanguageInfoRequerimentAndOperator>());
        }
        if(getPredicate().getSearch().getSearchLanguageInfoRequerimentAndOperatorList()==null){
            getPredicate().getSearch().setSearchLanguageInfoRequerimentAndOperatorList(new ArrayList<SearchLanguageInfoRequerimentAndOperator>());
        }
        if(getPredicate().getSearch().getSearchLanguageInfoRequerimentOrOperatorList()==null){
            getPredicate().getSearch().setSearchLanguageInfoRequerimentOrOperatorList(new ArrayList<SearchLanguageInfoRequerimentOrOperator>());
        }
        if(getPredicate().getSearch().getSearchProfessionalInfoRequerimentAndOperatorList()==null){
            getPredicate().getSearch().setSearchProfessionalInfoRequerimentAndOperatorList(new ArrayList<SearchProfessionalInfoRequerimentAndOperator>());
        }
        if(getPredicate().getSearch().getSearchProfessionalInfoRequerimentOrOperatorList()==null){
            getPredicate().getSearch().setSearchProfessionalInfoRequerimentOrOperatorList(new ArrayList<SearchProfessionalInfoRequerimentOrOperator>());
        }
        if(getPredicate().getSearch().getSearchRelocatingInfoRequerimentAndOperatorList()==null){
            getPredicate().getSearch().setSearchRelocatingInfoRequerimentAndOperatorList(new ArrayList<SearchRelocatingInfoRequerimentAndOperator>());
        }
        if(getPredicate().getSearch().getSearchRelocatingInfoRequerimentOrOperatorList()==null){
            getPredicate().getSearch().setSearchRelocatingInfoRequerimentOrOperatorList(new ArrayList<SearchRelocatingInfoRequerimentOrOperator>());
        }
        educationalAndCollector=new SearchEducationalInfoRequerimentAndOperator();
        educationalOrCollector=new SearchEducationalInfoRequerimentOrOperator();
        interestAreaAndCollector=new SearchInterestAreaRequerimentAndOperator();
        interestAreaOrCollector=new SearchInterestAreaRequerimentOrOperator();
        languageAndCollector=new SearchLanguageInfoRequerimentAndOperator();
        languageOrCollector=new SearchLanguageInfoRequerimentOrOperator();
        professionalAndCollector=new SearchProfessionalInfoRequerimentAndOperator();
        professionalOrCollector=new SearchProfessionalInfoRequerimentOrOperator();
        relocatingAndCollector=new SearchRelocatingInfoRequerimentAndOperator();
        relocatingOrCollector=new SearchRelocatingInfoRequerimentOrOperator();
    } 
    
    public void reinitFilter(){
        setPredicate(getNewPredicateInstance());
        setEntityList(new ArrayList<T>());
        setBaseEntityList(new ArrayList<T>());
        sex=null;
        minAge=null;
        maxAge=null;
        residenceCountry=null;
        residenceProvince=null;
        residenceTown=null;
        timeAvailability=null;
        requiredVehicle=null;    
        keywords=null;
        initSearch();
    }
    
    //This method should initialize baseList and entityList(filteredList)
    public abstract void initCandidates();
    
    public void removePersonalRequeriments(){
        getPredicate().getSearch().setSex(null);
        getPredicate().getSearch().setMaximumAge(null);
        getPredicate().getSearch().setMinimumAge(null);
        getPredicate().getSearch().setMinimumTimeAvailability(null);
        getPredicate().getSearch().setResidenceCountry(null);
        getPredicate().getSearch().setResidenceProvince(null);
        getPredicate().getSearch().setResidenceTown(null);
        getPredicate().getSearch().setRequiredVehicle(null);
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
        sort();
    }
    
    
    public void removeKeywords(){
        getPredicate().getSearch().setKeywords(null);
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }
    
    public void removeFromLanguageOrList(SearchLanguageInfoRequerimentOrOperator item){
        getPredicate().getSearch().getSearchLanguageInfoRequerimentOrOperatorList().remove(item);
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }
    public void removeFromLanguageAndList(SearchLanguageInfoRequerimentAndOperator item){
        getPredicate().getSearch().getSearchLanguageInfoRequerimentAndOperatorList().remove(item);
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
        sort();
    }
    public void removeFromEducationalOrList(SearchEducationalInfoRequerimentOrOperator item){
        getPredicate().getSearch().getSearchEducationalInfoRequerimentOrOperatorList().remove(item);
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }
    public void removeFromEducationalAndList(SearchEducationalInfoRequerimentAndOperator item){
        getPredicate().getSearch().getSearchEducationalInfoRequerimentAndOperatorList().remove(item);
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
        sort();
    }
    public void removeFromProfessionalOrList(SearchProfessionalInfoRequerimentOrOperator item){
        getPredicate().getSearch().getSearchProfessionalInfoRequerimentOrOperatorList().remove(item);
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }
    public void removeFromProfessionalAndList(SearchProfessionalInfoRequerimentAndOperator item){
        getPredicate().getSearch().getSearchProfessionalInfoRequerimentAndOperatorList().remove(item);        
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
        sort();
    }
    public void removeFromRelocatingOrList(SearchRelocatingInfoRequerimentOrOperator item){
        getPredicate().getSearch().getSearchRelocatingInfoRequerimentOrOperatorList().remove(item);
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }
    public void removeFromRelocatingAndList(SearchRelocatingInfoRequerimentAndOperator item){
        getPredicate().getSearch().getSearchRelocatingInfoRequerimentAndOperatorList().remove(item);
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
        sort();
    }
    public void removeFromInterestOrList(SearchInterestAreaRequerimentOrOperator item){
        getPredicate().getSearch().getSearchInterestAreaRequerimentOrOperatorList().remove(item);
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }
    public void removeFromInterestAndList(SearchInterestAreaRequerimentAndOperator item){
        getPredicate().getSearch().getSearchInterestAreaRequerimentAndOperatorList().remove(item);
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
        sort();
    }
            
    public void addPersonalRequeriments(){
        getPredicate().getSearch().setSex(sex);
        getPredicate().getSearch().setMaximumAge(maxAge);
        getPredicate().getSearch().setMinimumAge(minAge);
        getPredicate().getSearch().setMinimumTimeAvailability(timeAvailability);
        getPredicate().getSearch().setResidenceCountry(residenceCountry);
        getPredicate().getSearch().setResidenceProvince(residenceProvince);
        getPredicate().getSearch().setResidenceTown(residenceTown);
        getPredicate().getSearch().setRequiredVehicle(requiredVehicle);
        sex=null;
        maxAge=null;
        minAge=null;
        timeAvailability=null;
        residenceCountry=null;
        residenceProvince=null;
        residenceTown=null;
        requiredVehicle=null;
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
        sort();
    }
    
    public void addKeywords(){
        getPredicate().getSearch().setKeywords(keywords);
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }

    public void addSearchEducationalInfoRequeriment(){
        if(educationalOrCollector.getImportance()>0){
            educationalOrCollector.setSearch(getPredicate().getSearch());
            getPredicate().getSearch().getSearchEducationalInfoRequerimentOrOperatorList().add(educationalOrCollector);
            Collections.sort(getEntityList(),getNewComparatorInstance());
        }
        else{
            educationalAndCollector.setMinimumEducationalLevel(educationalOrCollector.getMinimumEducationalLevel());
            educationalAndCollector.setSector(educationalOrCollector.getSector());
            educationalAndCollector.setSearch(getPredicate().getSearch());
            getPredicate().getSearch().getSearchEducationalInfoRequerimentAndOperatorList().add(educationalAndCollector);
            CollectionsFilter.filter(getEntityList(), getPredicate());
        }
        reinitSearchEducationalRequeriment();
    }
    public void addSearchInterestAreaRequeriment(){
        if(interestAreaOrCollector.getImportance()>0){
            interestAreaOrCollector.setSearch(getPredicate().getSearch());
            getPredicate().getSearch().getSearchInterestAreaRequerimentOrOperatorList().add(interestAreaOrCollector);
            Collections.sort(getEntityList(),getNewComparatorInstance());
        }
        else{
            interestAreaAndCollector.setSearch(getPredicate().getSearch());
            interestAreaAndCollector.setJobPosition(interestAreaOrCollector.getJobPosition());
            interestAreaAndCollector.setMaximumDesiredSalary(interestAreaOrCollector.getMaximumDesiredSalary());
            interestAreaAndCollector.setSector(interestAreaOrCollector.getSector());
            getPredicate().getSearch().getSearchInterestAreaRequerimentAndOperatorList().add(interestAreaAndCollector);
            CollectionsFilter.filter(getEntityList(), getPredicate());
        }
        reinitSearchInterestRequeriment();
    }

    public void addSearchLanguageInfoRequeriment(){
        if(languageOrCollector.getImportance()>0){
            languageOrCollector.setSearch(getPredicate().getSearch());
            getPredicate().getSearch().getSearchLanguageInfoRequerimentOrOperatorList().add(languageOrCollector);
            Collections.sort(getEntityList(),getNewComparatorInstance());
        }
        else{
            languageAndCollector.setWritingLevel(languageOrCollector.getWritingLevel());
            languageAndCollector.setSearch(getPredicate().getSearch());
            languageAndCollector.setLanguage(languageOrCollector.getLanguage());
            languageAndCollector.setMinimumLanguageLevel(languageOrCollector.getMinimumLanguageLevel());
            languageAndCollector.setRequiredVideo(languageOrCollector.getRequiredVideo());
            getPredicate().getSearch().getSearchLanguageInfoRequerimentAndOperatorList().add(languageAndCollector);
            CollectionsFilter.filter(getEntityList(), getPredicate());
        }
        reinitSearchLanguageRequeriment();
    }
    
    public void addSearchProfessionalInfoRequeriment(){
        if(professionalOrCollector.getImportance()>0){
            professionalOrCollector.setSearch(getPredicate().getSearch());
            getPredicate().getSearch().getSearchProfessionalInfoRequerimentOrOperatorList().add(professionalOrCollector);
            Collections.sort(getEntityList(),getNewComparatorInstance());
        }
        else{
            professionalAndCollector.setSearch(getPredicate().getSearch());
            professionalAndCollector.setSector(professionalOrCollector.getSector());
            professionalAndCollector.setJobPosition(professionalOrCollector.getJobPosition());
            professionalAndCollector.setMinimumJobDuration(professionalOrCollector.getMinimumJobDuration());
            getPredicate().getSearch().getSearchProfessionalInfoRequerimentAndOperatorList().add(professionalAndCollector);
            CollectionsFilter.filter(getEntityList(), getPredicate());
        }
        reinitSearchProfessionalRequeriment();
    }
    
    public void addSearchRelocatingInfoRequeriment(){
        if(relocatingOrCollector.getImportance()>0){
            relocatingOrCollector.setSearch(getPredicate().getSearch());
            getPredicate().getSearch().getSearchRelocatingInfoRequerimentOrOperatorList().add(relocatingOrCollector);
            Collections.sort(getEntityList(),getNewComparatorInstance());
        }
        else{
            relocatingAndCollector.setCountry(relocatingOrCollector.getCountry());
            relocatingAndCollector.setProvince(relocatingOrCollector.getProvince());
            relocatingOrCollector.setSearch(getPredicate().getSearch());
            getPredicate().getSearch().getSearchRelocatingInfoRequerimentAndOperatorList().add(relocatingAndCollector);
            CollectionsFilter.filter(getEntityList(), getPredicate());
        }
        reinitSearchRelocatingRequeriment();
    }
    
    public void reinitSearchProfessionalRequeriment(){
        professionalAndCollector=new SearchProfessionalInfoRequerimentAndOperator();
        professionalOrCollector=new SearchProfessionalInfoRequerimentOrOperator();
    }
    
    public void reinitSearchEducationalRequeriment(){
        educationalAndCollector=new SearchEducationalInfoRequerimentAndOperator();
        educationalOrCollector=new SearchEducationalInfoRequerimentOrOperator();
    }
    
    public void reinitSearchLanguageRequeriment(){
        languageAndCollector=new SearchLanguageInfoRequerimentAndOperator();
        languageOrCollector=new SearchLanguageInfoRequerimentOrOperator();
    }
    
    public void reinitSearchRelocatingRequeriment(){
        relocatingAndCollector=new SearchRelocatingInfoRequerimentAndOperator();
        relocatingOrCollector=new SearchRelocatingInfoRequerimentOrOperator();
    }
    
    public void reinitSearchInterestRequeriment(){
        interestAreaAndCollector=new SearchInterestAreaRequerimentAndOperator();
        interestAreaOrCollector=new SearchInterestAreaRequerimentOrOperator();
    }
    
    /**
     * @return the search
     */
    public Search getSearch() {
        return getPredicate().getSearch();
    }


    /**
     * @return the educationalAndCollector
     */
    public SearchEducationalInfoRequerimentAndOperator getEducationalAndCollector() {
        return educationalAndCollector;
    }

    /**
     * @param educationalAndCollector the educationalAndCollector to set
     */
    public void setEducationalAndCollector(SearchEducationalInfoRequerimentAndOperator educationalAndCollector) {
        this.educationalAndCollector = educationalAndCollector;
    }

    /**
     * @return the educationalOrCollector
     */
    public SearchEducationalInfoRequerimentOrOperator getEducationalOrCollector() {
        return educationalOrCollector;
    }

    /**
     * @param educationalOrCollector the educationalOrCollector to set
     */
    public void setEducationalOrCollector(SearchEducationalInfoRequerimentOrOperator educationalOrCollector) {
        this.educationalOrCollector = educationalOrCollector;
    }

    /**
     * @return the interestAreaAndCollector
     */
    public SearchInterestAreaRequerimentAndOperator getInterestAreaAndCollector() {
        return interestAreaAndCollector;
    }

    /**
     * @param interestAreaAndCollector the interestAreaAndCollector to set
     */
    public void setInterestAreaAndCollector(SearchInterestAreaRequerimentAndOperator interestAreaAndCollector) {
        this.interestAreaAndCollector = interestAreaAndCollector;
    }

    /**
     * @return the interestAreaOrCollector
     */
    public SearchInterestAreaRequerimentOrOperator getInterestAreaOrCollector() {
        return interestAreaOrCollector;
    }

    /**
     * @param interestAreaOrCollector the interestAreaOrCollector to set
     */
    public void setInterestAreaOrCollector(SearchInterestAreaRequerimentOrOperator interestAreaOrCollector) {
        this.interestAreaOrCollector = interestAreaOrCollector;
    }

    /**
     * @return the languageAndCollector
     */
    public SearchLanguageInfoRequerimentAndOperator getLanguageAndCollector() {
        return languageAndCollector;
    }

    /**
     * @param languageAndCollector the languageAndCollector to set
     */
    public void setLanguageAndCollector(SearchLanguageInfoRequerimentAndOperator languageAndCollector) {
        this.languageAndCollector = languageAndCollector;
    }

    /**
     * @return the languageOrCollector
     */
    public SearchLanguageInfoRequerimentOrOperator getLanguageOrCollector() {
        return languageOrCollector;
    }

    /**
     * @param languageOrCollector the languageOrCollector to set
     */
    public void setLanguageOrCollector(SearchLanguageInfoRequerimentOrOperator languageOrCollector) {
        this.languageOrCollector = languageOrCollector;
    }

    /**
     * @return the professionalAndCollector
     */
    public SearchProfessionalInfoRequerimentAndOperator getProfessionalAndCollector() {
        return professionalAndCollector;
    }

    /**
     * @param professionalAndCollector the professionalAndCollector to set
     */
    public void setProfessionalAndCollector(SearchProfessionalInfoRequerimentAndOperator professionalAndCollector) {
        this.professionalAndCollector = professionalAndCollector;
    }

    /**
     * @return the professionalOrCollector
     */
    public SearchProfessionalInfoRequerimentOrOperator getProfessionalOrCollector() {
        return professionalOrCollector;
    }

    /**
     * @param professionalOrCollector the professionalOrCollector to set
     */
    public void setProfessionalOrCollector(SearchProfessionalInfoRequerimentOrOperator professionalOrCollector) {
        this.professionalOrCollector = professionalOrCollector;
    }

    /**
     * @return the relocatingAndCollector
     */
    public SearchRelocatingInfoRequerimentAndOperator getRelocatingAndCollector() {
        return relocatingAndCollector;
    }

    /**
     * @param relocatingAndCollector the relocatingAndCollector to set
     */
    public void setRelocatingAndCollector(SearchRelocatingInfoRequerimentAndOperator relocatingAndCollector) {
        this.relocatingAndCollector = relocatingAndCollector;
    }

    /**
     * @return the relocatingOrCollector
     */
    public SearchRelocatingInfoRequerimentOrOperator getRelocatingOrCollector() {
        return relocatingOrCollector;
    }

    /**
     * @param relocatingOrCollector the relocatingOrCollector to set
     */
    public void setRelocatingOrCollector(SearchRelocatingInfoRequerimentOrOperator relocatingOrCollector) {
        this.relocatingOrCollector = relocatingOrCollector;
    }
    
    public void cancelPersonal(){
        setSex(null);
        setMaxAge(null);
        setMinAge(null);
        setResidenceCountry(null);
        setResidenceProvince(null);
        setResidenceTown(null);
        setRequiredVehicle(null);
        setTimeAvailability(null);
    }
    
    public void cancelKeywords(){
        setKeywords(null);
    }   

    /**
     * @return the importance
     */
    public Integer getImportance() {
        return importance;
    }

    /**
     * @param importance the importance to set
     */
    public void setImportance(Integer importance) {
        this.importance = importance;
    }
    
    public void setChosenEntityByIdEntity(ActionEvent actionEvent){
        String idEntity=((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getParameter("idEntity");        
        setChosenEntity(getEntityFacade().find(new Integer(idEntity)));
    }

    public Integer dateDifference(Date compare){
        Date now=new Date();
        long diff=now.getTime()-compare.getTime();
        long days=diff / 1000 / 60 / 60 / 24 / 365;
        return (int)days;
    }

    /**
     * @return the scrollCandidates
     */
    public List<T> getScrollEntities() {
        Integer start=0;
        String param=((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getParameter("start");
        if(param!=null){
            start=new Integer(param);
        }
        Integer currentFacesCount=start+numberOfFaces;
        if(currentFacesCount>getEntityList().size()){
            currentFacesCount=getEntityList().size();
        }
        return getEntityList().subList(start, currentFacesCount);
    }

    /**
     * @return the sex
     */
    public Sex getSex() {
        return sex;
    }

    /**
     * @param sex the sex to set
     */
    public void setSex(Sex sex) {
        this.sex = sex;
    }

    /**
     * @return the minAge
     */
    public Integer getMinAge() {
        return minAge;
    }

    /**
     * @param minAge the minAge to set
     */
    public void setMinAge(Integer minAge) {
        this.minAge = minAge;
    }

    /**
     * @return the maxAge
     */
    public Integer getMaxAge() {
        return maxAge;
    }

    /**
     * @param maxAge the maxAge to set
     */
    public void setMaxAge(Integer maxAge) {
        this.maxAge = maxAge;
    }

    /**
     * @return the residenceCountry
     */
    public Country getResidenceCountry() {
        return residenceCountry;
    }

    /**
     * @param residenceCountry the residenceCountry to set
     */
    public void setResidenceCountry(Country residenceCountry) {
        this.residenceCountry = residenceCountry;
    }

    /**
     * @return the residenceProvince
     */
    public Province getResidenceProvince() {
        return residenceProvince;
    }

    /**
     * @param residenceProvince the residenceProvince to set
     */
    public void setResidenceProvince(Province residenceProvince) {
        this.residenceProvince = residenceProvince;
    }

    /**
     * @return the residenceTown
     */
    public Town getResidenceTown() {
        return residenceTown;
    }

    /**
     * @param residenceTown the residenceTown to set
     */
    public void setResidenceTown(Town residenceTown) {
        this.residenceTown = residenceTown;
    }

    /**
     * @return the timeAvailability
     */
    public TimeAvailability getTimeAvailability() {
        return timeAvailability;
    }

    /**
     * @param timeAvailability the timeAvailability to set
     */
    public void setTimeAvailability(TimeAvailability timeAvailability) {
        this.timeAvailability = timeAvailability;
    }

    /**
     * @return the requiredVehicle
     */
    public Boolean getRequiredVehicle() {
        return requiredVehicle;
    }

    /**
     * @param requiredVehicle the requiredVehicle to set
     */
    public void setRequiredVehicle(Boolean requiredVehicle) {
        this.requiredVehicle = requiredVehicle;
    }

    /**
     * @return the important
     */
    public Integer getImportant() {
        return important;
    }

    /**
     * @return the normal
     */
    public Integer getNormal() {
        return normal;
    }

    /**
     * @return the obligatory
     */
    public Integer getObligatory() {
        return obligatory;
    }

    /**
     * @return the keywords
     */
    public String getKeywords() {
        return keywords;
    }

    /**
     * @param keywords the keywords to set
     */
    public void setKeywords(String keywords) {
        this.keywords = keywords;
    }

    /**
     * @return the baseEntityList
     */
    public List<T> getBaseEntityList() {
        return baseEntityList;
    }

    /**
     * @param baseEntityList the baseEntityList to set
     */
    public void setBaseEntityList(List<T> baseEntityList) {
        this.baseEntityList = baseEntityList;
    }

    
    public C getNewComparatorInstance(){
        C newComparator=null;
        try {
            Type mySuperClass= this.getClass().getGenericSuperclass();
            while(!(mySuperClass instanceof ParameterizedType)){
                mySuperClass=((Class)mySuperClass).getGenericSuperclass();
            }
            Type comparatorType = ((ParameterizedType)mySuperClass).getActualTypeArguments()[2];
            Constructor constructor=null;
            for(Constructor constructorIt: (Class.forName(comparatorType.toString().split("<")[0])).getDeclaredConstructors()){
                if(constructorIt.getParameterTypes().length==1 && constructorIt.getParameterTypes()[0].isAssignableFrom(getPredicate().getClass())){
                    constructor=constructorIt;
                    break;
                }
            }
            if(constructor!=null){
                newComparator=(C)constructor.newInstance(getPredicate());
            }
        } catch (SecurityException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        }
        return newComparator;
    }
    
    public P getNewPredicateInstance(){
        P newPredicate=null;
        try {
            Type mySuperClass= this.getClass().getGenericSuperclass();
            while(!(mySuperClass instanceof ParameterizedType)){
                mySuperClass=((Class)mySuperClass).getGenericSuperclass();
            }
            Type predicateType = ((ParameterizedType)mySuperClass).getActualTypeArguments()[3];
            newPredicate=(P)(Class.forName(predicateType.toString().split("<")[0])).getConstructor().newInstance();
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(AbstractCandidateCapableFilterList.class.getName()).log(Level.SEVERE, null, ex);
        }
        return newPredicate;
    }

    public void filterFromFilteredList(){
        CollectionsFilter.filter(getEntityList(), getPredicate());
    }
    
    public void filterFromBaseList(){
        setEntityList(CollectionsFilter.filterOnNewCollection(baseEntityList, getPredicate()));
    }
    
    public void sort(){
        Collections.sort(getEntityList(),getNewComparatorInstance());
    }
    /**
     * @return the predicate
     */
    public P getPredicate() {
        return predicate;
    }

    /**
     * @param predicate the predicate to set
     */
    public void setPredicate(P predicate) {
        this.predicate = predicate;
    }
}
